package futbol.tacticas.concursantes.qualitycode.common;

import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import futbol.General;
import futbol.tacticas.SituacionJugadores;
import futbol.tacticas.concursantes.qualitycode.QCodeTactica;
import futbol.tacticas.concursantes.qualitycode.ctrlteam.QCtrlPlayer;

public class QUtils
{
  private static final Point POS_0 = new Point(0,0);
  public enum Filter { ADELANTE, ATRAS, ARRIBA, ABAJO };
  
  public static double distance(Point p1, Point p2)
  {
    final Point offset = new Point(distance(p1.x,p2.x), distance(p1.y,p2.y));
    return POS_0.distance(offset);
  }
  
  public static Point extraInterPolate(Point p1, Point p2, int dist)
  {
    final double ang = angle(p1, p2);
    final double x = Math.cos(ang) * dist;
    final double y = Math.sin(ang) * dist;
    final Point p = p1.getLocation();
    p.translate((int)x, (int)y);
    return p;
  }
  
  
  public static int distance(int n1, int n2)
  {
    return Math.abs(Math.abs(n1)-Math.abs(n2));
  }
  
  public static double angle(Point start, Point end)
  {
    return General.getAngulo(start.x, start.y, end.x, end.y);
  }
  
  public static boolean isValid(Point pos)
  {
    return pos.x != QCodeTactica.INVALID && pos.y != QCodeTactica.INVALID;
  }
  
  public static int randomCord(int maxCord)
  {
    if (Math.random() > 0.5)
      maxCord *= -1;
    
    int rCord = (int) -(Math.random()*maxCord);
    if (Math.abs(maxCord) < Math.abs(rCord))
      return maxCord;
    
    return rCord;
  }

  public static int siguienteJugador(SituacionJugadores sj, QPlayer player, List<QCtrlPlayer> excluirPlayers, boolean soloAdelante)
  {
    final int nExc[] = new int[excluirPlayers.size()+1];    
    for (int i = 0; i < excluirPlayers.size(); i++)
      nExc[i] = excluirPlayers.get(i).getID();
    
    nExc[nExc.length-1] = player.getID();
    
    int dev1[] = sj.getInfoMasCercano(sj.getMisJugadores(), sj.getMisJugadores()[player.getID()], nExc, soloAdelante);
    return dev1[0];
  }

  public static int siguienteJugador(SituacionJugadores sj, QPlayer player, boolean soloAdelante)
  {
    int nExc[] = { player.getID() };
    int dev1[] = sj.getInfoMasCercano(sj.getMisJugadores(), sj.getMisJugadores()[player.getID()], nExc, soloAdelante);
    return dev1[0];
  }

  /**
   * Regresa una nueva lista de jugadores utilizando el filtro seleccionado
   */
  public static <T extends QPlayer> List<T> filtrar(List<T> players, final Point punto, Filter filter)
  {
    final List<T> result = new ArrayList<T>(players);
    for (int i = result.size()-1; i >= 0; i--)
    {
      if (filter == Filter.ADELANTE && result.get(i).getX() < punto.getX())
          result.remove(i);
      else if (filter == Filter.ATRAS && result.get(i).getX() > punto.getX())
        result.remove(i);
      else if (filter == Filter.ARRIBA && result.get(i).getY() > punto.getY())
        result.remove(i);      
      else if (filter == Filter.ABAJO && result.get(i).getY() < punto.getY())
        result.remove(i);      
    }
    return result;
  }
  
  public static <T extends QPlayer> List<T> filtrar(List<T> players, final Point punto, int distancia, boolean adentro)
  {
    final List<T> result = new ArrayList<T>(players);
    for (int i = result.size()-1; i >= 0; i--)
    {
      final double dis = General.getDistancia(punto.x, punto.y, result.get(i).getX(), result.get(i).getY());
      if (adentro)
      {
        if (dis > distancia)
          result.remove(i);
      }
      else
      {
        if (dis < distancia)
          result.remove(i);
      }
    }
    return result;
  }

  /**
   * Regresa una nueva lista de jugadores ordenada de acuerdo a la cercania del punto.
   * El player en la posicion 0 es la mas cercana al punto. 
   * 
   * @return una lista de jugadores ordenada del mas cercano al mas lejano.
   */
  public static <T extends QPlayer> List<T> cercania(List<T> players, final Point punto)
  {
    final List<T> result = new ArrayList<T>();
    result.addAll(players);
    
    Collections.sort(result, new Comparator<T>()
    {
      public int compare(T player1, T player2)
      {
        final int dis1 = (int) General.getDistancia(player1.getX(), player1.getY(), punto.getX(), punto.getY());
        final int dis2 = (int) General.getDistancia(player2.getX(), player2.getY(), punto.getX(), punto.getY());
        
        return dis1-dis2;
      }
  
    });
    
    return result;
  }
}








